package com.explorex.infra.puma.gateway.netty.common.utils;


import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;

import java.io.IOException;
import java.util.Collections;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;

@Slf4j
public class HttpUtils {

    private static final MediaType mediaTypeBinary = MediaType.get("application/x-protobuf;charset=iso-8859-1");
    private static final MediaType mediaTypeJson = MediaType.get("application/json;");
    private static final String HTTP_REQUEST = "HTTP_REQUEST";
    private static final String MTransaction_FAILED = "failed";
    private static final String MTransaction_EXCEPTION = "exception";
    private static final OkHttpClient defaultHttpClient = newHttpClient();

    /**
     * 获取 Get 请求
     *
     * @param url
     * @return String 类型的数据
     */
    public static String doGet(final String url) {

        Request request = new Request.Builder()
                .url(url)
                .build();
        try (Response response = defaultHttpClient.newCall(request).execute()) {
            if (response.isSuccessful()) {
                return response.body().string();
            } else {
            }
        } catch (IOException e) {
            log.error("[HttpUtils] doGet exception url=-{} ", url, e);
        } finally {
        }
        return StringUtils.EMPTY;
    }

    /**
     * 同步post 二进制的数据
     *
     * @param url
     * @param body
     */
    public static byte[] doPost(final String url, final byte[] body, Map<String, String> header) {
        final RequestBody requestBody = RequestBody.create(mediaTypeJson, body);
        if (MapUtils.isEmpty(header)) {
            header = Collections.emptyMap();
        }
        Headers headers = Headers.of(header);
        Request request = new Request.Builder()
                .url(url)
                .headers(headers)
                .addHeader("Content-Type", "application/x-protobuf;charset=iso-8859-1")
                .addHeader("Accept", "application/x-protobuf;charset=iso-8859-1")
                .post(requestBody)
                .build();
        Call call = defaultHttpClient.newCall(request);
        try (Response response = call.execute()) {
            if (response.isSuccessful()) {
            } else {
            }
            return response.body().bytes();
        } catch (IOException e) {
            log.error("HttpUtils 二进制数据调用失败,url={},body={}", url, body, e);
        } finally {
        }
        return null;
    }

    /**
     * 同步post
     *
     * @param url
     * @param body
     */
    public static void doPost(final String url, final String body) {
        final RequestBody requestBody = RequestBody.create(mediaTypeJson, body);
        Request request = buildRequest(url, requestBody);
        Call call = defaultHttpClient.newCall(request);
        try (Response response = call.execute()) {
            if (response.isSuccessful()) {
            } else {
            }
        } catch (IOException e) {
            log.error("HttpUtils String数据调用失败,url={},body={}", url, body, e);
        } finally {
        }
    }

    /**
     * 异步post
     *
     * @param url
     * @param body
     */
    public static void doAsyncPost(final String url, final String body, final Function<IOException, Void> onFailureFunction) {
        final RequestBody requestBody = RequestBody.create(mediaTypeJson, body);
        Request request = buildRequest(url, requestBody);
        defaultHttpClient.newCall(request).enqueue(new Callback() {

            @Override
            public void onFailure(Call call, IOException e) {
                log.error("HttpUtils String数据调用失败,url={},body={}", url, body, e);

                if (onFailureFunction != null) {
                    onFailureFunction.apply(e);
                }
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                if (response.isSuccessful()) {
                } else {
                }
            }
        });
    }

    private static Request buildRequest(String url, RequestBody requestBody) {
        return new Request.Builder()
                .url(url)
                .addHeader("Content-Type", "application/json;")
                .addHeader("Accept", "application/json")
                .post(requestBody)
                .build();
    }

    /**
     * 异步 post 二进制数据
     *
     * @param url
     * @param body
     */
    public static void doAsyncPost(final String url, final byte[] body) {
        final RequestBody requestBody = RequestBody.create(mediaTypeBinary, body);
        Request request = new Request.Builder()
                .url(url)
                .post(requestBody)
                .build();

        defaultHttpClient.newCall(request).enqueue(new Callback() {

            @Override
            public void onFailure(Call call,  IOException e) {

            }

            @Override
            public void onResponse(Call call,Response response) throws IOException {
            }
        });
    }

    private static OkHttpClient newHttpClient() {
        OkHttpClient httpClient = new OkHttpClient.Builder()
                .connectTimeout(2, TimeUnit.SECONDS)
                .readTimeout(3, TimeUnit.SECONDS)
                .connectionPool(new ConnectionPool(80, 10, TimeUnit.SECONDS))
                .writeTimeout(3, TimeUnit.SECONDS)
//                .addInterceptor(new HttpCounterInterceptor())
                .build();
        return httpClient;
    }
}
